package com.sky.service.courier.impl;

import com.alisms.config.AlismsTemplate;
import com.sky.constant.StatusConstant;
import com.sky.dto.CourierTradeQueryDto;
import com.sky.dto.PickUpDTO;
import com.sky.mapper.courier.CourierMapper;
import com.sky.mapper.courier.CourierTradeOrderMapper;
import com.sky.mapper.courier.ShotUriMapper;
import com.sky.mapper.user.OrderDetailMapper;
import com.sky.mapper.user.OrderMapper;
import com.sky.pojo.Courier;
import com.sky.pojo.CourierTradeOrder;
import com.sky.pojo.Orders;
import com.sky.pojo.ShortUrl;
import com.sky.service.courier.CourierTradeOrderService;
import com.sky.shoturi.ShortUriGenerator;
import com.sky.utils.MapUtils;
import com.sky.vo.CourierTradeOrderVO;
import com.sky.vo.OrderDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Description CourierTradeOrderServiceImpl
 * @Author lyh
 * @Date 2024-11-04
 */
@Service
public class CourierTradeOrderServiceImpl implements CourierTradeOrderService {
    @Autowired
    private CourierTradeOrderMapper courierTradeOrderMapper;
    @Autowired
    private CourierMapper courierMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private AlismsTemplate alismsTemplate;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public List<CourierTradeOrderVO> queryCourierTradeOrderByCourierIdAndStatus(Integer status, Integer courierId) {
        List<CourierTradeOrderVO> courierTradeOrderVOList =courierTradeOrderMapper.selectByStatusAndCourierId(status,courierId);
        if(courierTradeOrderVOList!=null &&courierTradeOrderVOList.size()>0){
            courierTradeOrderVOList.forEach(courierTradeOrderVO -> {
                //String customerAddress = courierTradeOrderVO.getCustomerAddress();
                //String user = MapUtils.addressToLnglat(customerAddress);
                 String user = "116.343861,40.060889";
                //String shopAddress = courierTradeOrderVO.getShopAddress();
                //String shop = MapUtils.addressToLnglat(shopAddress);
                    String shop = "116.310511,40.056611";
                    Courier courier=courierMapper.getById(courierId);
                    String curLocation = courier.getCurLocation();
                    //商家和骑手的距离
                    double distanceShopToCou = MapUtils.calculateDistance(shop, curLocation);
                    courierTradeOrderVO.setShopAndCourierDistance(distanceShopToCou);
                    //店铺和客户的距离
                    double distanceShToUser = MapUtils.calculateDistance(shop, user);
                    courierTradeOrderVO.setShopAndCustomerDistance(distanceShToUser);
                //当前时间和客户期望时间的差值
                long between = Duration.between(LocalDateTime.now(), courierTradeOrderVO.getCustomerExpectedDeliveryTime()).get(ChronoUnit.SECONDS);
                courierTradeOrderVO.setCurrentTimeAndCustomerExpectedTime(between);
            });
           //设置排序
            //设置开始值为1
            AtomicInteger num = new AtomicInteger(1);
            courierTradeOrderVOList= courierTradeOrderVOList.stream()
                    .sorted(Comparator.comparing(CourierTradeOrderVO::getShopAndCustomerDistance))
                    .map(courierTradeOrderVO -> {
                        //设置序号   num.getAndIncrement() 获取值，然后加1  相当于a++
                        courierTradeOrderVO.setMarkSort( num.getAndIncrement());
                        return courierTradeOrderVO;
                    })
                    .collect(Collectors.toList());

        }
        return courierTradeOrderVOList;
    }

    /**
     * 根据订单号查询订单
     * @param tradeNo
     * @return
     */
    @Override
    public CourierTradeOrder queryCanceldTradeOrderByTradeNo(String tradeNo) {
        return courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(tradeNo);
    }

    /**
     * 骑手接单
     * @param courierId
     * @param tradeNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receivingOrder(Long courierId, String tradeNo) {
        if(courierId==null||tradeNo==null){
            throw new RuntimeException("参数不能为空");
        }
        CourierTradeOrder tradeOrder = courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(tradeNo);
        if(tradeOrder==null){
            throw new RuntimeException("该订单不存在");
        }
        //修改运单状态
        courierTradeOrderMapper.updateTradeOrderByTradeNo(tradeNo, CourierTradeOrder.DELIVORING);
        //修改订单状态
        orderMapper.updateOrderByNumber(tradeOrder.getOrderNumber(),Orders.TOBEPICKEDUP);

        //        3.发送短信给用户，并且附带地址，用户点击可以查看骑手和用户的位置
        //String url=" http://cangqiong.free.idcfengye.com/rider.html?tradeNo="+tradeNo+"&courierId="+courierId+"&expire=null";
        //System.out.println("发送短信给用户：url"+url);
        sendMessage(courierId,tradeOrder);
    }
    @Autowired
    private ShortUriGenerator shortUriGenerator;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ShotUriMapper shotUriMapper;
    private void sendMessage(Long courierId, CourierTradeOrder tradeOrder) {
        //String url=" http://cangqiong.free.idcfengye.com/rider.html?tradeNo="+tradeOrder.getTradeNo()+"&courierId="+courierId+"&expire="+tradeOrder.getCustomerExpectedDeliveryTime();
        //生成长链
        String fullUrl = shortUriGenerator.getFullUrl(tradeOrder.getTradeNo(), courierId, tradeOrder.getCustomerExpectedDeliveryTime());
        //短编码
        String code = "";
        while(true){
            code = shortUriGenerator.creatKey();
            long index = 0L;
            int hashCode = code.hashCode();
            //hashCode为负进行处理
            if(hashCode<0){
                index = 2147483648L+Math.abs(hashCode);
            }else {
                index = hashCode;
            }
            //判断是否重复
            Boolean res = redisTemplate.opsForValue().getBit("short_code", index);
            if(!res){
                //设置bit位
                redisTemplate.opsForValue().setBit("short_code",index,true);
                break;
            }
        }
        //保存入库
        String shortUrl = shortUriGenerator.getShortUrl(code);
        ShortUrl shotUri = ShortUrl.builder()
                .shortCode(code)
                .shortUrl(shortUrl)
                .fullUrl(fullUrl)
                .expireTime(tradeOrder.getCustomerExpectedDeliveryTime())
                .tradeNo(tradeOrder.getTradeNo())
                .build();
        shotUriMapper.save(shotUri);
        ///短链通过短信给到用户 , ps:附带连接的短信审核要求较高，个人无法申请
        //alismsTemplate.sendMessage("15501521617",shortUrl);
        System.out.println("--------发送短信给客户,地址:"+shortUrl);
    }

    @Override
    public String loadRouteInfo(String tradeNo, Long courierId) {
        CourierTradeOrder courierTradeOrder = courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(tradeNo);
        if(courierTradeOrder==null||CourierTradeOrder.TRADE_COMPLETE.equals(courierTradeOrder.getWaybillStatus())||CourierTradeOrder.CANCLE_TRADE.equals(courierTradeOrder.getWaybillStatus())){
            throw new RuntimeException("该订单已无法查看");
        }
        //获取用户的经纬度
        String customerAddress = courierTradeOrder.getCustomerAddress();
        String customerLocation = MapUtils.addressToLnglat(customerAddress);
        String shopAddress = courierTradeOrder.getShopAddress();
        String shopLocation = MapUtils.addressToLnglat(shopAddress);
        Courier courier = courierMapper.getById(Math.toIntExact(courierId));
        String curLocation = courier.getCurLocation();
        return customerLocation+"_"+shopLocation+"_"+curLocation;
    }

    @Override
    public String getLongUrl(String code) {
        String longUrl= shotUriMapper.getLongUrl(code);
        return longUrl;
    }

    @Override
    public List<OrderDetailVO> confirmPickUpList(String tradeNo) {
        if(tradeNo==null){
            throw new RuntimeException("查询条件不存在");
        }
        CourierTradeOrder tradeOrder = courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(tradeNo);
        if(tradeOrder==null){
            throw new RuntimeException("订单不存在");
        }
        List<OrderDetailVO> list=orderDetailMapper.selectByOrderNumber(tradeOrder.getOrderNumber());
        return list;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void confirmPickUp(PickUpDTO pickUpDTO) {
        if(pickUpDTO==null||pickUpDTO.getTradeNo()==null){
            throw new RuntimeException("参数异常");
        }
        CourierTradeOrder tradeOrder = courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(String.valueOf(pickUpDTO.getTradeNo()));
        if(tradeOrder==null){
            throw new RuntimeException("订单不存在");
        }
        if(pickUpDTO.getStatus()==3) {
            courierTradeOrderMapper.updateTradeOrderByTradeNo(String.valueOf(pickUpDTO.getTradeNo()), CourierTradeOrder.CONFIRM_TRADE);
            orderMapper.updateOrderByNumber(tradeOrder.getOrderNumber(), Orders.TOBEDELIVERED);
        }else if(pickUpDTO.getStatus()==4){
            courierTradeOrderMapper.updateTradeOrderByTradeNo2(String.valueOf(pickUpDTO.getTradeNo()), CourierTradeOrder.TRADE_COMPLETE,LocalDateTime.now());

            orderMapper.updateOrderByNumber(tradeOrder.getOrderNumber(), Orders.COMPLETE_ORDER);
        }
    }

    @Override
    public List<CourierTradeOrderVO> queryWaybillsByDate(CourierTradeQueryDto dto) {
        List<CourierTradeOrderVO> list=courierTradeOrderMapper.queryWaybillsByDate(dto);
        list.forEach(courierTradeOrderVO -> {
            String user = "116.343861,40.060889";
            String shop = "116.310511,40.056611";
            Courier courier=courierMapper.getById(Math.toIntExact(dto.getCourierId()));
            String curLocation = courier.getCurLocation();
            //商家和骑手的距离
            double distanceShopToCou = MapUtils.calculateDistance(shop, curLocation);
            courierTradeOrderVO.setShopAndCourierDistance(distanceShopToCou);
            //店铺和客户的距离
            double distanceShToUser = MapUtils.calculateDistance(shop, user);
            courierTradeOrderVO.setShopAndCustomerDistance(distanceShToUser);
        });
        AtomicInteger sort = new AtomicInteger(1);
        //序号，商家和客户的距离排序，添加序号
          list= list.stream().sorted(Comparator.comparing(CourierTradeOrderVO::getShopAndCustomerDistance))
                .map(vo->{
                    vo.setMarkSort(sort.getAndIncrement());
                    return  vo;
                }).collect(Collectors.toList());

        return list;
    }
}
